import {
  getNewCartGoods,
  reqCheckAllCart,
  reqDeleteCart,
  reqFindCartList,
  reqInsertCart,
  reqMergeLocalCart,
  reqUpdateCartSku
} from '@/api/cart'
export default {
  namespaced: true,
  state: () => {
    return {
      list: []
    }
  },
  mutations: {
    setList(state, newList) {
      state.list = newList
    },
    insertCart(state, goods) {
      const idx = state.list.findIndex((item) => item.skuId === goods.skuId)
      if (idx >= 0) {
        state.list[idx].count += goods.count
      } else {
        state.list.unshift(goods)
      }
    },
    deleteCart(state, goods) {
      const idx = state.list.findIndex((item) => item.skuId === goods.skuId)
      state.list.splice(idx, 1)
    },
    updateCart(state, goods) {
      const sku = state.list.find((item) => item.skuId === goods.skuId)
      if (sku) {
        sku.isEffective = goods.isEffective
        sku.nowPrice = goods.nowPrice
        sku.stock = goods.stock
      }
    },
    singleCheck(state, { goods, selected }) {
      const sku = state.list.find((item) => item.skuId === goods.skuId)
      sku.selected = selected
    },
    checkEffectAll(state, selected) {
      state.list.forEach((item) => {
        if (item.isEffective) {
          item.selected = selected
        }
      })
    },
    changeCount(state, { goods, count }) {
      const sku = state.list.find((item) => item.skuId === goods.skuId)
      sku.count = count
    }
  },
  actions: {
    async asyncInsertCart(context, goods) {
      if (context.rootState.user.profile.token) {
        const { skuId, count } = goods
        await reqInsertCart({ skuId, count })
        await context.dispatch('asyncUpdateCart')
      } else {
        context.commit('insertCart', goods)
      }
    },
    async asyncDeleteCart(context, goods) {
      if (context.rootState.user.profile.token) {
        await reqDeleteCart([goods.skuId])
        await context.dispatch('asyncUpdateCart')
      } else {
        context.commit('deleteCart', goods)
      }
    },
    asyncUpdateCart(context) {
      return new Promise((resolve) => {
        if (context.rootState.user.profile.token) {
          reqFindCartList().then((res) => {
            context.commit('setList', res.result)
            resolve()
          })
        } else {
          const arr = context.state.list.map((item) => {
            return getNewCartGoods(item.skuId)
          })
          Promise.all(arr).then((res) => {
            res.forEach((item, i) => {
              context.commit('updateCart', {
                skuId: context.state.list[i].skuId,
                ...item.result
              })
            })
            resolve()
          })
        }
      })
    },
    async asyncSingleCheck(context, { goods, selected }) {
      if (context.rootState.user.profile.token) {
        await reqUpdateCartSku({ skuId: goods.skuId, selected })
        await context.dispatch('asyncUpdateCart')
      } else {
        context.commit('singleCheck', { goods, selected })
      }
    },
    async asyncCheckEffectAll(context, selected) {
      if (context.rootState.user.profile.token) {
        const skuIds = context.getters.effectiveList.map((item) => item.skuId)
        await reqCheckAllCart({ selected, ids: skuIds })
        await context.dispatch('asyncUpdateCart')
      } else {
        context.commit('checkEffectAll', selected)
      }
    },
    async asyncChangeCount(context, { goods, count }) {
      if (context.rootState.user.profile.token) {
        await reqUpdateCartSku({ skuId: goods.skuId, count })
        await context.dispatch('asyncUpdateCart')
      } else {
        context.commit('changeCount', { goods, count })
      }
    },
    async asyncMergeLocalCart(context) {
      const cartList = context.state.list.map(({ skuId, selected, count }) => ({
        skuId,
        selected,
        count
      }))
      await reqMergeLocalCart(cartList)
      await context.dispatch('asyncUpdateCart')
    }
  },
  getters: {
    effectiveList(state) {
      return state.list.filter((item) => item.stock > 0 && item.isEffective)
    },
    effectiveTotal(state, getters) {
      return getters.effectiveList.reduce((acc, cur) => acc + cur.count, 0)
    },
    effectiveTotalPrice(state, getters) {
      return getters.effectiveList.reduce(
        (acc, cur) => acc + cur.count * cur.nowPrice,
        0
      )
    },
    ineffectiveList(state) {
      return state.list.filter((item) => !(item.stock > 0 && item.isEffective))
    },
    selectedList(state, getters) {
      return getters.effectiveList.filter((item) => item.selected)
    },
    selectedAllCounts(state, getters) {
      return getters.selectedList.reduce((acc, cur) => acc + cur.count, 0)
    },
    selectedAllPrice(state, getters) {
      return getters.selectedList
        .reduce((acc, cur) => acc + cur.count * cur.nowPrice, 0)
        .toFixed(2)
    },
    isAllEffectSelected(state, getters) {
      return (
        getters.effectiveList.every((item) => item.selected) &&
        getters.effectiveList.length > 0
      )
    }
  }
}
